<template>
  <div class="derived-factor-container">
    <div class="factor-list-container">
      <div class="list-header">
        <el-tag
            type="primary"
            size="large"
            effect="dark"
            style="font-size: 20px; padding: 30px 20px;"
        >
          <el-icon :size="30"
                   style="
    position: relative;
    top: 10px;   /* 想往下调多少就改多少，正数向下，负数向上 */
  ">
            <DataAnalysis /></el-icon>
          衍生因子管理
        </el-tag>
        <!-- 按钮卡片 -->
        <el-card class="action-card" shadow="hover">
          <el-button type="primary" @click="createFactorDialogVisible = true">
            <el-icon><Plus /></el-icon>新建衍生因子模板
          </el-button>
          <el-button @click="exportFactors">
            <el-icon><Download /></el-icon>导出JSON
          </el-button>
        </el-card>
        <!-- 多条件搜索 -->
        <el-card class="search-filters" shadow="hover" >
          <el-row :gutter="10">
            <el-col :span="6">
              <el-input
                  v-model="searchFilters.name"
                  placeholder="搜索因子名称"
                  prefix-icon="el-icon-search"
                  clearable
                  @input="onSearch"
              ></el-input>
            </el-col>
            <el-col :span="6">
              <el-input
                  v-model="searchFilters.code"
                  placeholder="搜索因子代码"
                  prefix-icon="el-icon-search"
                  clearable
                  @input="onSearch"
              ></el-input>
            </el-col>
            <el-col :span="4">
              <el-select
                  v-model="searchFilters.operator"
                  placeholder="算子类型"
                  clearable
                  @change="onSearch"
              >
                <el-option label="加法" value="ADD"></el-option>
                <el-option label="减法" value="SUBTRACT"></el-option>
                <el-option label="乘法" value="MULTIPLY"></el-option>
                <el-option label="除法" value="DIVIDE"></el-option>
                <el-option label="均值" value="MEAN"></el-option>
                <el-option label="加权平均" value="WEIGHTED_MEAN"></el-option>
                <el-option label="标准差" value="STD"></el-option>
                <el-option label="方差" value="VARIANCE"></el-option>
                <el-option label="中位数" value="MEDIAN"></el-option>
                <el-option label="排序" value="RANK"></el-option>
                <el-option label="标准化" value="ZSCORE"></el-option>
                <el-option label="缩尾处理" value="WINSORIZE"></el-option>
                <el-option label="对数变换" value="LOG"></el-option>
                <el-option label="差分" value="DIFF"></el-option>
                <el-option label="主成分分析" value="PCA"></el-option>
                <el-option label="因子分析" value="FACTOR_ANALYSIS"></el-option>
                <el-option label="聚类分析" value="CLUSTERING"></el-option>
                <el-option label="回归分析" value="REGRESSION"></el-option>
              </el-select>
            </el-col>
            <el-col :span="4">
              <el-select
                  v-model="searchFilters.enabled"
                  placeholder="状态"
                  clearable
                  @change="onSearch"
              >
                <el-option label="启用" :value="true"></el-option>
                <el-option label="禁用" :value="false"></el-option>
              </el-select>
            </el-col>
            <el-col :span="4">
              <el-button type="primary" @click="onSearch">
                <el-icon><Search /></el-icon>
                搜索</el-button>
            </el-col>
          </el-row>
        </el-card>
      </div>

      <div class="table-wrapper">
        <el-table
            :data="currentPageFactors"
            @row-click="selectFactor"
            highlight-current-row
            style="width: 100%"
            v-loading="loading"
        >
          <el-table-column prop="factorName" label="因子名称" width="100"></el-table-column>
          <el-table-column prop="factorCode" label="因子代码" width="150"></el-table-column>
          <el-table-column prop="operator" label="算子" width="100">
            <template #default="{ row }">
              <el-tag :type="getOperatorTagType(row.operator)">{{ getOperatorName(row.operator) }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column
              label="输入因子"
              width="280"
              show-overflow-tooltip
          >
            <template #default="{ row }">
              {{ row.inputFactorNames || '无' }}
            </template>
          </el-table-column>
          <el-table-column prop="enabled" label="状态" width="100">
            <template #default="{ row }">
              <el-tag :type="row.enabled ? 'success' : 'info'">
                {{ row.enabled ? '启用' : '禁用' }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="updateTime" label="更新时间" width="180">
            <template #default="{ row }">
              {{ formatDate(row.updateTime) }}
            </template>
          </el-table-column>
          <el-table-column label="操作" width="480">
            <template #default="{ row }">
              <div style="display: flex; align-items: center; justify-content: flex-end;">
                <el-input
                    v-model="row.fundCode"
                    placeholder="输入基金代码计算衍生因子值"
                    style="width: 300px; margin-right: 10px;"
                ></el-input>
                <el-button size="mini" type="primary" plain  @click.stop="calculateFactor(row)" :loading="calculating">计算</el-button>
                <el-button size="mini" type="info" plain @click.stop="editFactor(row)">编辑</el-button>
                <el-button size="mini" type="danger" plain @click.stop="deleteFactor(row)">删除</el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>
      </div>

    </div>

    <!-- 计算结果显示弹窗 -->
    <el-dialog
        v-model="calculationResultVisible"
        title="衍生因子计算结果"
        width="600px"
        :close-on-click-modal="false"
    >
      <div v-if="calculationResult" class="calculation-result">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="因子名称">
            {{ calculationResult.factorName }}
          </el-descriptions-item>
          <el-descriptions-item label="因子代码">
            {{ calculationResult.factorCode }}
          </el-descriptions-item>
          <el-descriptions-item label="基金代码">
            {{ calculationResult.fundCode }}
          </el-descriptions-item>
          <el-descriptions-item label="因子值">
            <span class="factor-value">{{ calculationResult.factorValue }}</span>
          </el-descriptions-item>
          <el-descriptions-item label="计算时间">
            {{ formatDate(calculationResult.calculationTime) }}
          </el-descriptions-item>
          <el-descriptions-item label="计算状态">
            <el-tag :type="calculationResult.success ? 'success' : 'danger'">
              {{ calculationResult.success ? '成功' : '失败' }}
            </el-tag>
          </el-descriptions-item>
        </el-descriptions>

        <div v-if="calculationResult.inputData" class="input-data-section">
          <h4>输入因子数据</h4>
          <el-table :data="calculationResult.inputData" size="small" border>
            <el-table-column prop="factorName" label="因子名称" width="150"></el-table-column>
            <el-table-column prop="factorValue" label="因子值" width="120"></el-table-column>
            <el-table-column prop="weight" label="权重" width="80"></el-table-column>
          </el-table>
        </div>

        <div v-if="calculationResult.calculationSteps" class="calculation-steps">
          <h4>计算步骤</h4>
          <el-steps :active="calculationResult.calculationSteps.length" direction="vertical" size="small">
            <el-step 
              v-for="(step, index) in calculationResult.calculationSteps" 
              :key="index"
              :title="step.title"
              :description="step.description"
            ></el-step>
          </el-steps>
        </div>
      </div>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="calculationResultVisible = false">取消</el-button>
          <el-button 
            type="primary" 
            @click="saveCalculationResult" 
            :loading="savingCalculation"
            :disabled="!calculationResult || !calculationResult.success"
          >
            保存到数据库
          </el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 创建或编辑衍生因子对话框 -->
    <el-dialog
        v-model="createFactorDialogVisible"
        :title="selectedFactor.id ? '编辑衍生因子' : '新建衍生因子'"
        width="800px"
        @closed="resetForm"
    >
      <el-form :model="selectedFactor" label-width="120px" class="factor-form">
        <el-form-item label="因子名称" required>
          <el-input v-model="selectedFactor.name" placeholder="输入因子名称"></el-input>
        </el-form-item>

        <el-form-item label="因子代码" required>
          <el-input v-model="selectedFactor.factorCode" placeholder="输入因子代码"></el-input>
        </el-form-item>

        <el-form-item label="输入因子" required>
          <el-select 
            v-model="selectedFactor.inputFactors" 
            multiple 
            placeholder="选择输入因子"
            filterable
            @change="onInputFactorsChange"
          >
            <el-option 
              v-for="factor in availableFactors" 
              :key="factor.code" 
              :label="factor.name" 
              :value="factor.code"
            ></el-option>
          </el-select>
          <div class="factor-count-info">
            已选择 {{ selectedFactor.inputFactors ? selectedFactor.inputFactors.length : 0 }} 个因子
          </div>
        </el-form-item>

        <el-form-item label="算子配置" required>
          <div class="operator-config">
            <div v-for="(factor, index) in selectedFactor.inputFactors" :key="index" class="operator-item">
              <div class="operator-header">
                <span class="factor-name">{{ getFactorName(factor) }}</span>
                <el-button size="mini" type="danger" @click="removeFactor(index)" v-if="selectedFactor.inputFactors.length > 1">删除</el-button>
              </div>
              <div class="operator-content">
                <el-select 
                  v-model="selectedFactor.operators[index]" 
                  placeholder="选择算子"
                  style="width: 120px; margin-right: 10px;"
                >
                  <el-option label="加法" value="ADD"></el-option>
                  <el-option label="减法" value="SUBTRACT"></el-option>
                  <el-option label="乘法" value="MULTIPLY"></el-option>
                  <el-option label="除法" value="DIVIDE"></el-option>
                  <el-option label="加权加法" value="WEIGHTED_ADD"></el-option>
                  <el-option label="加权乘法" value="WEIGHTED_MULTIPLY"></el-option>
                </el-select>
                <el-input-number
                  v-model="selectedFactor.weights[index]"
                  :min="0"
                  :max="1"
                  :precision="4"
                  :step="0.1"
                  placeholder="权重"
                  style="width: 100px;"
                ></el-input-number>
              </div>
            </div>
            <el-button size="mini" type="primary" @click="addFactor" style="margin-top: 10px;">添加因子</el-button>
          </div>
        </el-form-item>

        <el-form-item label="计算参数">
          <el-input 
            v-model="selectedFactor.parameters" 
            type="textarea" 
            placeholder="输入计算参数（JSON格式）"
            :rows="4"
          ></el-input>
          <div class="param-help">
            <el-button size="mini" @click="showParameterHelp">参数说明</el-button>
            <el-button size="mini" @click="generateParameters">生成参数</el-button>
          </div>
        </el-form-item>

        <el-form-item label="计算周期">
          <el-select v-model="selectedFactor.calculationPeriod" placeholder="选择计算周期">
            <el-option label="日频" value="DAILY"></el-option>
            <el-option label="周频" value="WEEKLY"></el-option>
            <el-option label="月频" value="MONTHLY"></el-option>
            <el-option label="季频" value="QUARTERLY"></el-option>
          </el-select>
        </el-form-item>

        <el-form-item label="回溯期数">
          <el-input-number
              v-model="selectedFactor.lookbackPeriod"
              :min="1"
              :max="252"
              placeholder="输入回溯期数"
          ></el-input-number>
        </el-form-item>

        <el-form-item label="状态">
          <el-switch v-model="selectedFactor.enabled"></el-switch>
        </el-form-item>

        <el-form-item label="描述">
          <el-input
              v-model="selectedFactor.description"
              type="textarea"
              placeholder="输入因子描述"
              :rows="3"
          ></el-input>
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="createFactorDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="saveFactor" :loading="saving">保存</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 参数说明对话框 -->
    <el-dialog v-model="parameterHelpVisible" title="参数配置说明" width="600px">
      <div class="parameter-help-content">
        <div v-for="operator in operatorParameters" :key="operator.type" class="operator-help">
          <h4>{{ operator.name }}</h4>
          <p>{{ operator.description }}</p>
          <div class="parameter-example">
            <strong>参数示例：</strong>
            <pre>{{ operator.example }}</pre>
          </div>
        </div>
      </div>
    </el-dialog>

    <!-- 测试结果对话框 -->
    <el-dialog v-model="testResultVisible" title="测试计算结果" width="800px">
      <div class="test-result-content">
        <div class="result-summary">
          <el-row :gutter="20">
            <el-col :span="8">
              <div class="result-item">
                <div class="result-label">计算状态</div>
                <div class="result-value" :class="testResult.success ? 'success' : 'error'">
                  {{ testResult.success ? '成功' : '失败' }}
                </div>
              </div>
            </el-col>
            <el-col :span="8">
              <div class="result-item">
                <div class="result-label">数据点数</div>
                <div class="result-value">{{ testResult.dataPoints || 0 }}</div>
              </div>
            </el-col>
            <el-col :span="8">
              <div class="result-item">
                <div class="result-label">计算耗时</div>
                <div class="result-value">{{ testResult.duration || 0 }}ms</div>
              </div>
            </el-col>
          </el-row>
        </div>

        <div v-if="testResult.error" class="error-message">
          <strong>错误信息：</strong>
          <pre>{{ testResult.error }}</pre>
        </div>

        <div v-if="testResult.sampleData" class="sample-data">
          <h4>样本数据：</h4>
          <el-table :data="testResult.sampleData" height="300">
            <el-table-column prop="date" label="日期" width="100"></el-table-column>
            <el-table-column prop="value" label="因子值" width="100"></el-table-column>
            <el-table-column prop="fundCode" label="基金代码" width="100"></el-table-column>
          </el-table>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { ref, reactive, computed, onMounted, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import axios from "axios";
import {DataAnalysis, Download, Plus, Search, Upload} from '@element-plus/icons-vue'
// 创建带基地址的 axios 实例
const api = axios.create({
  baseURL: '/api', // 匹配代理配置
  timeout: 10000
})

export default {
  name: 'DerivedFactor',
  components: {Search, Plus, DataAnalysis, Download},
  setup() {
    // 响应式数据
    const factors = ref([])
    const selectedFactor = ref({})
    const searchFilters = ref({
      name: '',
      code: '',
      operator: '',
      enabled: null
    })
    const saving = ref(false)
    const loading = ref(false)
    const calculating = ref(false)
    const testing = ref(false)
    const savingCalculation = ref(false)
    const createFactorDialogVisible = ref(false)
    const parameterHelpVisible = ref(false)
    const testResultVisible = ref(false)
    const calculationResultVisible = ref(false)
    const testResult = ref({})
    const calculationResult = ref({})
    const currentPage = ref(1)
    const pageSize = ref(10)
    const availableFactors = ref([
      { code: '简单收益率因子', name: '简单收益率因子' },
      { code: '年化收益率因子', name: '年化收益率因子' },
      { code: '对数收益率因子', name: '对数收益率因子' },
      { code: '波动率因子', name: '波动率因子' },
      { code: '夏普比率因子', name: '夏普比率因子' },
      { code: '最大回撤因子', name: '最大回撤因子' },
      { code: '下行风险因子', name: '下行风险因子' },
      { code: '相对强弱指数因子', name: '相对强弱指数因子' },
      { code: '移动平均值因子', name: '移动平均值因子' },
      { code: '申购开放频率因子', name: '申购开放频率因子' },
      { code: '赎回开放频率因子', name: '赎回开放频率因子' }
    ])

    const calculateFactor = async (row) => {
      console.log("calculateFactor called with row:", row); // 调试信息
      if (!row.fundCode) {
        ElMessage.warning('请输入基金代码');
        return;
      }
      
      // 先检查衍生因子是否可计算
      try {
        const checkResponse = await axios.get(`http://localhost:8080/derived/dev/check-calculable/${row.factorCode}`);
        if (!checkResponse.data.calculable) {
          ElMessage.warning(`衍生因子不可计算: ${checkResponse.data.message}`);
          return;
        }
      } catch (error) {
        console.error('检查衍生因子可计算性失败:', error);
        // 继续尝试计算，不阻止用户
      }
      
      try {
        calculating.value = true;
        const response = await axios.post(`http://localhost:8080/derived/dev/calculate/${row.factorCode}/${row.fundCode}`);
        
        if (response.data && response.data.success) {
          // 构建计算结果对象
          calculationResult.value = {
            factorName: row.factorName,
            factorCode: row.factorCode,
            fundCode: row.fundCode,
            factorValue: response.data.factorValue,
            calculationTime: new Date(),
            success: true,
            inputData: [
              // 这里可以根据实际返回的数据构建输入因子数据
              { factorName: '输入因子1', factorValue: '0.123', weight: '0.5' },
              { factorName: '输入因子2', factorValue: '0.456', weight: '0.5' }
            ],
            calculationSteps: [
              { title: '获取输入因子数据', description: '成功获取2个输入因子的数据' },
              { title: '应用权重', description: '对输入因子应用权重配置' },
              { title: '执行计算', description: `使用${row.operator}算子进行计算` },
              { title: '生成结果', description: `计算完成，因子值: ${response.data.factorValue}` }
            ]
          };
          
          // 显示计算弹窗
          calculationResultVisible.value = true;
        } else {
          // 构建错误结果对象
          calculationResult.value = {
            factorName: row.factorName,
            factorCode: row.factorCode,
            fundCode: row.fundCode,
            factorValue: null,
            calculationTime: new Date(),
            success: false,
            errorMessage: response.data.message || '未知错误'
          };
          
          // 显示计算弹窗
          calculationResultVisible.value = true;
        }
      } catch (error) {
        console.error('计算失败:', error);
        let errorMsg = '计算失败';
        
        if (error.response?.data?.message) {
          errorMsg = error.response.data.message;
        } else if (error.response?.status === 400) {
          errorMsg = '请求参数错误';
        } else if (error.response?.status === 404) {
          errorMsg = '衍生因子或基金代码不存在';
        } else if (error.response?.status === 500) {
          errorMsg = '服务器内部错误';
        } else if (error.message) {
          errorMsg = error.message;
        }
        
        // 构建错误结果对象
        calculationResult.value = {
          factorName: row.factorName,
          factorCode: row.factorCode,
          fundCode: row.fundCode,
          factorValue: null,
          calculationTime: new Date(),
          success: false,
          errorMessage: errorMsg
        };
        
        // 显示计算弹窗
        calculationResultVisible.value = true;
      } finally {
        calculating.value = false;
      }
    };

    const operatorParameters = ref([
      {
        type: 'ADD',
        name: '加法',
        description: '对多个因子进行加法运算',
        example: '{"weights": [0.5, 0.5]}'
      },
      {
        type: 'SUBTRACT',
        name: '减法',
        description: '对多个因子进行减法运算',
        example: '{"weights": [0.5, 0.5]}'
      },
      {
        type: 'MULTIPLY',
        name: '乘法',
        description: '对多个因子进行乘法运算',
        example: '{"weights": [0.5, 0.5]}'
      },
      {
        type: 'DIVIDE',
        name: '除法',
        description: '对多个因子进行除法运算',
        example: '{"weights": [0.5, 0.5]}'
      },
      {
        type: 'WEIGHTED_MEAN',
        name: '加权平均',
        description: '对多个因子进行加权平均',
        example: '{"weights": [0.3, 0.4, 0.3]}'
      },
      {
        type: 'ZSCORE',
        name: '标准化',
        description: '对因子进行Z-score标准化',
        example: '{"window": 60, "method": "rolling"}'
      },
      {
        type: 'WINSORIZE',
        name: '缩尾处理',
        description: '对因子进行缩尾处理',
        example: '{"lower": 0.01, "upper": 0.99}'
      },
      {
        type: 'PCA',
        name: '主成分分析',
        description: '对多个因子进行PCA降维',
        example: '{"n_components": 3, "method": "eigen"}'
      }
    ])
    const validateParameters = (parameters) => {
      // 检查是否包含 weights 属性
      if (!parameters || !parameters.weights) {
        return false;
      }

      // 检查 weights 是否是数组
      if (!Array.isArray(parameters.weights)) {
        return false;
      }

      // 检查 weights 数组是否至少包含一个元素
      if (parameters.weights.length === 0) {
        return false;
      }

      // 检查 weights 数组中的元素是否都是数字
      for (const weight of parameters.weights) {
        if (typeof weight !== 'number') {
          return false;
        }
      }

      // 如果所有检查都通过，返回 true
      return true;
    };

    // 计算属性
    const filteredFactors = computed(() => {
      if (!searchFilters.value.name && !searchFilters.value.code && !searchFilters.value.operator && searchFilters.value.enabled === null) return factors.value
      return factors.value.filter(factor =>
        (searchFilters.value.name ? factor.factorName && factor.factorName.toLowerCase().includes(searchFilters.value.name.toLowerCase()) : true) &&
        (searchFilters.value.code ? factor.factorCode && factor.factorCode.toLowerCase().includes(searchFilters.value.code.toLowerCase()) : true) &&
        (searchFilters.value.operator ? factor.operator && factor.operator.toLowerCase().includes(searchFilters.value.operator.toLowerCase()) : true) &&
        (searchFilters.value.enabled !== null ? factor.enabled === searchFilters.value.enabled : true)
      )
    })

    // 当前页显示的因子
    const currentPageFactors = computed(() => {
      const start = (currentPage.value - 1) * pageSize.value
      const end = start + pageSize.value
      return filteredFactors.value.slice(start, end)
    })

    // 方法
    const loadFactors = async () => {
      loading.value = true;
      try {
        const response = await axios.get(`http://localhost:8080/derived/dev/noPage`);
        factors.value = response.data.map(factor => {
          const formattedFactor = { ...factor };
          // 初始化 fundCode
          formattedFactor.fundCode = formattedFactor.fundCode || '';
          // 处理输入因子名称
          if (factor.components && factor.components.length > 0) {
            formattedFactor.inputFactorNames = factor.components
              .map(component => component.inputFactor)
              .join(', ');
          } else {
            formattedFactor.inputFactorNames = '无';
          }
          return formattedFactor;
        });
      } catch (error) {
        console.error('加载衍生因子失败:', error);
        ElMessage.error('加载衍生因子列表失败');
      } finally {
        loading.value = false;
      }
    };

    // 处理分页大小变化
    const handleSizeChange = (size) => {
      pageSize.value = size
      currentPage.value = 1 // 重置到第一页
    }

    // 处理页码变化
    const handlePageChange = (page) => {
      currentPage.value = page
    }

    const selectFactor = (factor) => {
      selectedFactor.value = { ...factor }
      // 确保输入因子是数组格式
      if (typeof selectedFactor.value.inputFactors === 'string') {
        try {
          selectedFactor.value.inputFactors = JSON.parse(selectedFactor.value.inputFactors)
        } catch (e) {
          selectedFactor.value.inputFactors = []
        }
      }
    }

    const editFactor = (factor) => {
      selectFactor(factor)
      createFactorDialogVisible.value = true
    }

    const deleteFactor = async (factor) => {
      const id = factor.id || factor;
      ElMessageBox.confirm('确认删除?', '提示', { type: 'warning' })
        .then(async () => {
          await axios.delete(`http://localhost:8080/derived/dev/deleteById/${id}`);
          await loadFactors();
        });
    }
    const saveFactor = async () => {
      if (!selectedFactor.value.name || !selectedFactor.value.factorCode) {
        ElMessage.warning('请填写因子名称和因子代码')
        return
      }

      if (!selectedFactor.value.inputFactors || selectedFactor.value.inputFactors.length === 0) {
        ElMessage.warning('请选择至少一个输入因子')
        return
      }

      saving.value = true
      try {
        // 构建后端期望的数据结构
        const factorData = {
          name: selectedFactor.value.name,
          factorCode: selectedFactor.value.factorCode,
          operator: selectedFactor.value.operators && selectedFactor.value.operators.length > 0 
            ? selectedFactor.value.operators[0] 
            : 'ADD', // 默认使用第一个算子作为主算子
          inputFactors: selectedFactor.value.inputFactors,
          parameters: JSON.stringify({
            weights: selectedFactor.value.weights || [],
            operators: selectedFactor.value.operators || [],
            factors: selectedFactor.value.inputFactors.map((factor, index) => ({
              factorCode: factor,
              factorName: getFactorName(factor),
              operator: selectedFactor.value.operators[index] || 'ADD',
              weight: selectedFactor.value.weights[index] || (1.0 / selectedFactor.value.inputFactors.length)
            }))
          }),
          calculationPeriod: selectedFactor.value.calculationPeriod || 'DAILY',
          lookbackPeriod: selectedFactor.value.lookbackPeriod || 20,
          enabled: selectedFactor.value.enabled !== undefined ? selectedFactor.value.enabled : true,
          description: selectedFactor.value.description || ''
        };

        console.log('保存因子数据:', factorData); // 调试日志

        if (selectedFactor.value.id) {
          await axios.put(`http://localhost:8080/derived/dev/update/${selectedFactor.value.id}`, factorData)
        } else {
          await axios.post(`http://localhost:8080/derived/dev/create`, factorData)
        }

        ElMessage.success('保存成功')
        createFactorDialogVisible.value = false
        await loadFactors()
      } catch (error) {
        console.error('保存失败:', error); // 调试日志
        const errorMsg = error.response?.data?.message || error.message || '保存失败'
        ElMessage.error(`保存失败: ${errorMsg}`)
      } finally {
        saving.value = false
      }
    }
    const generateDefaultParameters = (inputFactors) => {
      if (!inputFactors || inputFactors.length === 0) {
        return '{"weights": []}'
      }
      
      const weights = inputFactors.map(() => 1.0 / inputFactors.length) // 平均权重
      return JSON.stringify({ weights }, null, 2)
    }

    const resetForm = () => {
      selectedFactor.value = {
        name: '',
        factorCode: '',
        inputFactors: [],
        operators: [],
        weights: [],
        parameters: '{"weights": []}',
        calculationPeriod: 'DAILY',
        lookbackPeriod: 20,
        enabled: true,
        description: ''
      }
    }

    // 多因子支持方法
    const onInputFactorsChange = () => {
      const factors = selectedFactor.value.inputFactors || [];
      const currentOperators = selectedFactor.value.operators || [];
      const currentWeights = selectedFactor.value.weights || [];
      
      // 调整算子数组长度
      while (currentOperators.length < factors.length) {
        currentOperators.push('ADD');
      }
      while (currentOperators.length > factors.length) {
        currentOperators.pop();
      }
      
      // 调整权重数组长度
      while (currentWeights.length < factors.length) {
        currentWeights.push(1.0 / factors.length);
      }
      while (currentWeights.length > factors.length) {
        currentWeights.pop();
      }
      
      // 重新计算权重，确保总和为1
      if (currentWeights.length > 0) {
        const totalWeight = currentWeights.reduce((sum, weight) => sum + weight, 0);
        if (totalWeight !== 1) {
          currentWeights.forEach((weight, index) => {
            currentWeights[index] = weight / totalWeight;
          });
        }
      }
      
      selectedFactor.value.operators = currentOperators;
      selectedFactor.value.weights = currentWeights;
      
      // 生成新的参数配置
      generateParameters();
    }

    const addFactor = () => {
      if (!selectedFactor.value.inputFactors) {
        selectedFactor.value.inputFactors = [];
      }
      selectedFactor.value.inputFactors.push('');
      onInputFactorsChange();
    }

    const removeFactor = (index) => {
      selectedFactor.value.inputFactors.splice(index, 1);
      onInputFactorsChange();
    }

    const getFactorName = (factorCode) => {
      const factor = availableFactors.value.find(f => f.code === factorCode);
      return factor ? factor.name : factorCode;
    }

    const generateParameters = () => {
      const factors = selectedFactor.value.inputFactors || [];
      const operators = selectedFactor.value.operators || [];
      const weights = selectedFactor.value.weights || [];
      
      const config = {
        factors: factors.map((factor, index) => ({
          factorCode: factor,
          factorName: getFactorName(factor),
          operator: operators[index] || 'ADD',
          weight: weights[index] || (1.0 / factors.length)
        })),
        weights: weights,
        operators: operators
      };
      
      selectedFactor.value.parameters = JSON.stringify(config, null, 2);
    }

    const exportFactors = () => {
      if (factors.value.length === 0) {
        ElMessage.warning('没有可导出的数据')
        return
      }

      const dataStr = JSON.stringify(factors.value, null, 2)
      const dataBlob = new Blob([dataStr], { type: 'application/json' })
      const url = URL.createObjectURL(dataBlob)
      const link = document.createElement('a')
      link.href = url
      const now = new Date();
      const yyyy = now.getFullYear();
      const mm = String(now.getMonth() + 1).padStart(2, '0');
      const dd = String(now.getDate()).padStart(2, '0');
      link.download = `derived_factors_${yyyy}-${mm}-${dd}.json`;
      link.click()
      URL.revokeObjectURL(url)
    }

    const saveCalculationResult = async () => {
      if (!calculationResult.value || !calculationResult.value.success) {
        ElMessage.warning('没有有效的计算结果可以保存');
        return;
      }

      savingCalculation.value = true;
      try {
        const saveData = {
          factorCode: calculationResult.value.factorCode,
          fundCode: calculationResult.value.fundCode,
          factorValue: calculationResult.value.factorValue,
          calculationTime: calculationResult.value.calculationTime
        };

        const response = await axios.post('http://localhost:8080/derived/dev/save-calculation-result', saveData);
        
        if (response.data && response.data.success) {
          ElMessage.success('计算结果已保存到数据库');
          calculationResultVisible.value = false;
        } else {
          ElMessage.error(`保存失败: ${response.data.message || '未知错误'}`);
        }
      } catch (error) {
        console.error('保存计算结果失败:', error);
        const errorMsg = error.response?.data?.message || error.message || '保存失败';
        ElMessage.error(`保存计算结果失败: ${errorMsg}`);
      } finally {
        savingCalculation.value = false;
      }
    };

    const onOperatorChange = () => {
      // 根据算子类型设置默认参数
      const operator = operatorParameters.value.find(op => op.type === selectedFactor.value.operator);
      if (operator) {
        selectedFactor.value.parameters = operator.example;
      } else {
        selectedFactor.value.parameters = '{}';
      }

      // 限制输入因子只能选择两个
      if (selectedFactor.value.inputFactors && selectedFactor.value.inputFactors.length > 2) {
        selectedFactor.value.inputFactors = selectedFactor.value.inputFactors.slice(0, 2);
        ElMessage.warning('只能选择两个输入因子');
      }
    };

    const showParameterHelp = () => {
      parameterHelpVisible.value = true
    }

    const getOperatorTagType = (operator) => {
      const typeMap = {
        'ADD': 'primary',
        'SUBTRACT': 'primary',
        'MULTIPLY': 'primary',
        'DIVIDE': 'primary',
        'MEAN': 'success',
        'WEIGHTED_MEAN': 'success',
        'STD': 'success',
        'VARIANCE': 'success',
        'MEDIAN': 'success',
        'RANK': 'warning',
        'ZSCORE': 'warning',
        'WINSORIZE': 'warning',
        'LOG': 'warning',
        'DIFF': 'warning',
        'PCA': 'danger',
        'FACTOR_ANALYSIS': 'danger',
        'CLUSTERING': 'danger',
        'REGRESSION': 'danger'
      }
      return typeMap[operator] || 'info'
    }

    const getOperatorName = (operator) => {
      const nameMap = {
        'ADD': '加法',
        'SUBTRACT': '减法',
        'MULTIPLY': '乘法',
        'DIVIDE': '除法',
        'MEAN': '均值',
        'WEIGHTED_MEAN': '加权平均',
        'STD': '标准差',
        'VARIANCE': '方差',
        'MEDIAN': '中位数',
        'RANK': '排序',
        'ZSCORE': '标准化',
        'WINSORIZE': '缩尾',
        'LOG': '对数',
        'DIFF': '差分',
        'PCA': 'PCA',
        'FACTOR_ANALYSIS': '因子分析',
        'CLUSTERING': '聚类',
        'REGRESSION': '回归'
      }
      return nameMap[operator] || operator
    }

    const formatDate = (date) => {
      if (!date) return ''
      const d = new Date(date)
      return `${d.getFullYear()}-${(d.getMonth() + 1).toString().padStart(2, '0')}-${d.getDate().toString().padStart(2, '0')} ${d.getHours().toString().padStart(2, '0')}:${d.getMinutes().toString().padStart(2, '0')}`
    }

    const onSearch = () => {
      currentPage.value = 1
    }

    const clearSearch = () => {
      searchFilters.value = {
        name: '',
        code: '',
        operator: '',
        enabled: null
      }
      currentPage.value = 1
    }

    // 监听输入因子变化，自动更新参数
    watch(() => selectedFactor.value.inputFactors, (newFactors) => {
      if (newFactors && newFactors.length > 0) {
        selectedFactor.value.parameters = generateDefaultParameters(newFactors)
      }
    }, { deep: true })

    // 生命周期
    onMounted(() => {
      loadFactors()
    })

    // 当搜索关键词变化时重置页码
    watch(searchFilters, () => {
      currentPage.value = 1
    })

    return {
      factors,
      selectedFactor,
      searchFilters,
      saving,
      loading,
      calculating,
      testing,
      savingCalculation,
      createFactorDialogVisible,
      parameterHelpVisible,
      testResultVisible,
      calculationResultVisible,
      testResult,
      calculationResult,
      availableFactors,
      operatorParameters,
      filteredFactors,
      currentPageFactors,
      currentPage,
      pageSize,

      loadFactors,
      selectFactor,
      editFactor,
      deleteFactor,
      saveFactor,
      calculateFactor,
      saveCalculationResult,
      resetForm,
      onInputFactorsChange,
      addFactor,
      removeFactor,
      getFactorName,
      generateParameters,
      exportFactors,
      onOperatorChange,
      showParameterHelp,
      getOperatorTagType,
      getOperatorName,
      formatDate,
      handleSizeChange,
      handlePageChange,
      onSearch,
      clearSearch,
      generateDefaultParameters
    }
  }
}
</script>

<style scoped>
/* 调整容器样式 */
.derived-factor-container {
  padding: 15px; /* 减少padding */
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
  flex-shrink: 0;
}

.header h2 {
  margin: 0;
  color: #333;
  font-size: 24px;
  font-weight: 600;
}

.header-actions {
  display: flex;
  gap: 10px;
}

.factor-list-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  border: 1px solid #ddd;
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.list-header {
  padding: 15px 20px; /* 增加左右padding */
  border-bottom: 1px solid #eee;
  background: #f9f9f9;
  display: flex;
  justify-content: space-between;
  align-items: flex-start; /* 改为flex-start，让内容从顶部对齐 */
  flex-shrink: 0;
  gap: 20px; /* 添加间距 */
}
.header-left {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 300px; /* 确保左侧有足够空间 */
}
.header-left h3 {
  margin: 0;
  color: #333;
  font-size: 20px; /* 稍微增大字体 */
  font-weight: 600;
}
.header-actions {
  display: flex;
  gap: 10px;
}

.list-header h3 {
  margin: 0 0 10px 0;
  color: #333;
  font-size: 18px;
  font-weight: 600;
}

.search-filters {
  flex: 1; /* 让搜索区域占据剩余空间 */
  justify-content: flex-end; /* 搜索区域右对齐 */
  /*width:600px ;*/
  display: inline-block;   /* 关键：宽度随内容 */
  width: auto;             /* 让浏览器根据内容算宽 */
}

.table-wrapper {
  flex: 1;
  overflow: auto;
}

.factor-form {
  background: white;
  padding: 20px;
  border-radius: 4px;
  border: 1px solid #eee;
}

.parameter-help {
  margin-top: 5px;
  font-size: 12px;
  color: #666;
}

.parameter-help-content {
  max-height: 400px;
  overflow-y: auto;
}

.operator-help {
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 1px solid #eee;
}

.operator-help h4 {
  margin: 0 0 5px 0;
  color: #333;
  font-size: 16px;
}

.operator-help p {
  margin: 0 0 10px 0;
  color: #666;
  font-size: 14px;
}

.parameter-example {
  background: #f5f5f5;
  padding: 10px;
  border-radius: 4px;
}

.parameter-example pre {
  margin: 0;
  font-size: 12px;
  font-family: 'Courier New', Courier, monospace;
}

.test-result-content {
  max-height: 500px;
  overflow-y: auto;
}

.result-summary {
  margin-bottom: 20px;
}

.result-item {
  text-align: center;
  padding: 10px;
  background: #f9f9f9;
  border-radius: 4px;
}

.result-label {
  font-size: 12px;
  color: #666;
  margin-bottom: 5px;
}

.result-value {
  font-size: 16px;
  font-weight: bold;
  color: #333;
}

.result-value.success {
  color: #67c23a;
}

.result-value.error {
  color: #f56c6c;
}

.error-message {
  margin: 15px 0;
  padding: 10px;
  background: #fef0f0;
  border: 1px solid #fbc4c4;
  border-radius: 4px;
  color: #f56c6c;
}

.error-message pre {
  margin: 10px 0 0 0;
  font-size: 12px;
  font-family: 'Courier New', Courier, monospace;
}

.sample-data {
  margin-top: 20px;
}

.sample-data h4 {
  margin: 0 0 10px 0;
  color: #333;
  font-size: 16px;
  font-weight: 600;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

/* 多因子支持样式 */
.factor-count-info {
  margin-top: 5px;
  font-size: 12px;
  color: #666;
}

.operator-config {
  margin-top: 10px;
}

.operator-item {
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 10px;
  margin-bottom: 10px;
  background: #fafafa;
}

.operator-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.operator-content {
  display: flex;
  align-items: center;
  gap: 10px;
}

.factor-name {
  font-weight: 500;
  color: #333;
}

.param-help {
  margin-top: 5px;
  display: flex;
  gap: 10px;
}

:deep(.el-dialog) {
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

:deep(.el-dialog__header) {
  padding: 20px;
  border-bottom: 1px solid #eee;
  background: #fff;
}

:deep(.el-dialog__body) {
  padding: 20px;
}

:deep(.el-dialog__footer) {
  padding: 20px;
  border-top: 1px solid #eee;
}

:deep(.el-table) {
  --el-table-header-bg-color: #f5f7fa;
  --el-table-bg-color: #ffffff;
  --el-table-border-color: #ebeef5;
  --el-table-tr-bg-color: #ffffff;
}

:deep(.el-tag--primary) {
  background-color: #e6f7ff;
  color: #1890ff;
  border-color: #91d5ff;
}

:deep(.el-tag--success) {
  background-color: #f6ffed;
  color: #52c41a;
  border-color: #b7eb8f;
}

:deep(.el-tag--danger) {
  background-color: #fff1f0;
  color: #f5222d;
  border-color: #ffccc7;
}

.list-header {
  padding: 15px;
  border-bottom: 1px solid #eee;
  background: #f9f9f9;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.factor-list-container {
  flex: 1;
  border: 1px solid #ddd;
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.24);
}

.el-table .cell {
  white-space: nowrap;
}

:deep(.el-pagination) {
  background-color: #fff;
}

/* 计算弹窗样式 */
.calculation-result {
  padding: 10px 0;
}

.factor-value {
  font-size: 18px;
  font-weight: bold;
  color: #409eff;
}

.input-data-section,
.calculation-steps {
  margin-top: 20px;
}

.input-data-section h4,
.calculation-steps h4 {
  margin: 0 0 10px 0;
  color: #333;
  font-size: 16px;
  font-weight: 600;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
/* 让表格左右各留 20 px 空白 */
.table-wrapper {
  padding: 0 20px;   /* 新增 */
  flex: 1;
  overflow: auto;
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .list-header {
    flex-direction: column;
    align-items: stretch;
    gap: 15px;
  }

  .header-left {
    min-width: auto;
  }

  .search-filters {
    justify-content: flex-start;
  }
}

@media (max-width: 768px) {
  .header-actions {
    flex-direction: column;
    gap: 8px;
  }

  .header-actions .el-button {
    width: 100%;
  }
}
</style>